﻿// Juli.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <thread>
#include <opencv2/opencv.hpp>
#define tick_freq 63

#include "Juli/Julianna.h"
#include "Juli/activities.h"
#include "main.h"
#include "Juli/TextBox.h"
#include "Juli/Juli_chart.h"
#include "Juli/EditTextBox.h"
#include "Juli/Juli_inputs_line.h"
#include "Juli/Juli_keyboards.h"

#include "E:\temp\ugui v0.3\ugui.h"

using namespace std;
using namespace cv;

void disp_text(int x, int y, char c);
void disp_text(int x, int y, const char* s);
void on_mouse(int event, int x, int y, int flags, void* ustc);
Scalar rgb565_to_color(int rgb565);
int color_to_rgb565(Scalar c);
int TP_Scan_statue(void);
void dida(void);


CRITICAL_SECTION cs;

Mat can(Screen_height, Screen_width, CV_8UC3);

int draw_background = 1;
Scalar pen(0, 0, 0);
Scalar back_color(255, 255, 255);

int _x = 0, _y = 0;
//int fontSize = 24;
float fontScale = 0.43;

struct
{
	int x[5], y[5];
} tp_dev;

unsigned int time_ms()
{
	DWORD endTime = GetTickCount();//计时结束
	return endTime;
}
void disp_text(int x, int y, const char* s)
{
	static char ss[2] = { 0, 0 };

	while (*s)
	{
		disp_text(x, y, *s);
		s++;
		x += fontSize / 2;
		if (x >= Screen_width)
		{
			y += fontSize;
			x = 0;
		}
	}
}
void disp_text(int x, int y, char c)
{
	static char ss[2] = { 0, 0 };
	ss[0] = c;
	if (draw_background)
	{
		LCD_fill_with(x, y, fontSize / 2, fontSize, BACK_COLOR);
	}
	putText(can, ss, Point(x, y + fontSize), CV_FONT_HERSHEY_SIMPLEX, fontScale, pen);
}

int PEN = 0;
int mx = 0, my = 0;
void on_mouse(int event, int x, int y, int flags, void* ustc)
{
	mx = x;
	my = y;
	if (event == CV_EVENT_LBUTTONDOWN) //鼠标左键按下事件发生
	{
		PEN = 1;
		//Point pt(x, y);//获取当前点的横纵坐标值
		////char temp[16];
		////sprintf(temp, "(%d,%d)", pt.x, pt.y);//打印当前坐标值
		////cvPutText(src, temp, pt, &font, cvScalar(255, 255, 255, 0)); //在图像中打印当前坐标值
		//circle(can, pt, 2, Scalar(255, 0, 0), -1);//在在图像当前坐标点下画圆
		////cvShowImage("src", src);
	}
	//else if (event == CV_EVENT_MOUSEMOVE)
	//{
	//}
	else if (event == CV_EVENT_LBUTTONUP)
	{
		PEN = 0;
	}
}

void sends(const char* s)
{
	cout << s;
	textBoxView_addString(boxView, (char*)s);
	juli_show_ui(boxView_ui, ByPass);
}
DWORD WINAPI touch_manager(LPVOID arg);
DWORD WINAPI ticks_thread(LPVOID lpParamter)
{
	while (true)
	{
		Sleep(10);
		EnterCriticalSection(&cs); //进入临界区，如果有其他线程则等待
		lily_tick();
		LeaveCriticalSection(&cs); //退出临界区，其他线程可以进来了
	}
	return 0L;
}

int screen_flush()
{
	imshow("src", can);
	return 0;
}
DWORD WINAPI key_cap(LPVOID arg)
{
	while (1)
	{
		int c = cvWaitKey(10);
		if (c == -1)
			continue;
		cout << (int)c << " " << c << "\n";
	}

	return 0;
}

//JUI inputs_key_typed(char* msg);
//JUI inputs_control_event(char* id);
void uGUI_run(void);
int main()
{
	//lily_out = sends;
	lily_millis = time_ms;
	lily_init();

	can = 0;
	namedWindow("src", WINDOW_AUTOSIZE);
	cvSetMouseCallback("src", on_mouse, 0);

	int i, j;
	int x = 0, y = 0;
	back_color = rgb565_to_color(BACK_COLOR);
	can = back_color;

	init_julianna();
	textBoxView_setup();
	activity_one_init();

	collection_fun_math_kit();
	//chart_test_demo();
	chart_file_init();
	editTextBoxView_file_init();
	//editTextBox_test_demo();


	juli_show_up();

	//uGUI_run();

	InitializeCriticalSection(&cs);
	HANDLE hThread = CreateThread(NULL, 0, ticks_thread, NULL, 0, NULL);
	HANDLE hThread2 = CreateThread(NULL, 0, touch_manager, NULL, 0, NULL);
	//CreateThread(NULL, 0, key_cap, NULL, 0, NULL);
	public_a_timer(screen_flush, Hz(20));
	public_a_fun_link_n("dida", dida, 0);
	while (true)
	{
		//EnterCriticalSection(&cs); //进入临界区，如果有其他线程则等待
		int c = waitKey(3);
		//LeaveCriticalSection(&cs); //退出临界区，其他线程可以进来了

		if (c != -1)
		{
			//cout << c<<" "<<char(c)<<endl;
			char s[2] = { 0, 0 };
			s[0] = c;
			//JUI call;

			if (*s == '\r' )
			{
				*s = '\n';
				//call  = (JUI)kb_interface_control_type(s);
			}
			//call = inputs_control_event(s);
			/*else
			{

			}*/
			pipe_release_data(kb_type, s, 1);
			//call = (JUI)kb_interface_getc(s);// inputs_key_typed(s);
		//juli_show_ui(call, ByPass);

		}
		while (front != rear)
		{
			if (tasks_[front] == NULL)
			{
				lily_out("null ptr");
				if (++front >= Tasks_LEN)
					front = 0;
				continue;
			}
			EnterCriticalSection(&cs); //进入临界区，如果有其他线程则等待
			if (tasks_[front]() > 0)
			{
				addTask_(tasks_[front]);
			}
			LeaveCriticalSection(&cs); //退出临界区，其他线程可以进来了
			if (++front >= Tasks_LEN)
				front = 0;
		}
	}
}

#define osDelay Sleep
DWORD WINAPI touch_manager(LPVOID arg)
{
	Presse_Statue ste = None;
	// int x, y;
	while (1)
	{
		ste = (Presse_Statue)TP_Scan_statue();
		if (ste == None)
		{
			Sleep(10);
			continue;
		}
		EnterCriticalSection(&cs); //进入临界区，如果有其他线程则等待
		int d = juli_boardcast_event(tp_dev.x[0], tp_dev.y[0], ste);
		LeaveCriticalSection(&cs); //退出临界区，其他线程可以进来了

		osDelay(d);
	}
	return 0;
}

const int bm = 0x1f;
const int gm = 0x3f << 5;
const int rm = 0x1f << 11;

Scalar rgb565_to_color(int rgb565)
{
	int r, g, b;
	b = rgb565 & 0x1f;
	g = (rgb565 & (0x3f * 32)) >> 5;	// 2^5 = 32
	r = (rgb565 & (0x1f * 2048)) >> 11; // 2^11 = 2048
	return Scalar(b << 3, g << 2, r << 3);
}

int color_to_rgb565(Scalar c)
{
	int r, g, b;

	b = c[0];
	g = c[1];
	r = c[2];
	// &0x1f;
	b = b >> 3;
	g >>= 2;
	r >>= 3;
	return (r << 11) | (g << 5) | b;
}

//int rgb888_torgb565(int co)
//{
//	int r, g, b;
//	unsigned char* c = (unsigned char*)&co;
//	b = c[0];
//	g = c[1];
//	r = c[2];
//	// &0x1f;
//	b = b >> 3;
//	g >>= 2;
//	r >>= 3;
//	return (r << 11) | (g << 5) | b;
//}

void LCD_Clear(int Color)
{
	//清屏
	can = back_color;
}

void LCD_DrawPoint(short x, short y) //画点
{
	can.at<Vec3b>(y, x) = Vec3b(pen[0], pen[1], pen[2]);
}

void LCD_Fast_DrawPoint(u16 x, u16 y, u32 color)
{
	auto c = rgb565_to_color(color);
	can.at<Vec3b>(y, x) = Vec3b(c[0], c[1], c[2]); // c:rgb 565
}

void LCD_fill_with(short sx, short sy, short width, short height, int color)
{
	if (!width || !height)return;
	can(Rect(sx, sy, width, height)) = rgb565_to_color(color);
}

int TP_Scan_statue()
{
	int s = None;
	static int last_down = 0;
	if (PEN) //有按键按下
	{

		tp_dev.x[0] = mx;
		tp_dev.y[0] = my;

		if (!last_down) //之前没有被按下
		{
			s = PressedDown;
		}
		else
			s = Moving; //Moving
	}
	else
	{
		if (last_down) //之前是被按下的
		{
			s = PressedUp;
		}
		else //之前就没有被按下
		{
			s = None;
		}
	}
	last_down = PEN;
	return s; //返回当前的触屏状态
}

void set_p(short x, short y, int color)
{
	char* c = (char*)&color;

	can.at<Vec3b>(y, x) = Vec3b(c[2], c[1], c[0]); // c:rgb 565
}

void uGUI_run()
{
	typedef void (*PPRTO)(UG_S16, UG_S16, UG_COLOR);
	static UG_GUI guio;
	UG_Init(&guio, (PPRTO)set_p, 480, 800);
	/*4 100*/
	ug_DrawRoundFrame(4, 448, 100, 480, 15);
	LCD_DrawRectangle(4, 448, 100, 480);
	UG_FillCircle(100, 400, 30, C_BEIGE);

	//test_window();
	//UG_Update();
	return;

	UG_WINDOW window1;
	UG_TEXTBOX textbox1;
	// . . .
	UG_TextboxCreate(&window1, &textbox1, TXB_ID_0, 10, 10, 100, 100);
	UG_TextboxSetText(&window1, TXB_ID_0, (char*)"hello World");

	UG_TextboxShow(&window1, TXB_ID_0);

}


const double T = 1.059463f; // 2^(1/12), 十二均律
float pt(int n)
{
	float x = 1.0f;


	while (n-- > 0)
		x *= T;
	return x;
}

void dida()
{
	Sleep(50); Beep(880 / pt(7), 400);	//2
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(0), 400);  //6
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(0), 400);  //6
	Sleep(50); Beep(880 / pt(2), 800);	//5-


	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(7), 400);	//2
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(4), 800);	//4-


	Sleep(50); Beep(880 / pt(7), 400);	//2
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(0), 400);  //6
	Sleep(50); Beep(880 * pt(3), 400);	//1(+)
	Sleep(50); Beep(880 / pt(0), 400);  //6
	Sleep(50); Beep(880 / pt(2), 800);	//5-


	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(2), 400);	//5
	Sleep(50); Beep(880 / pt(4), 400);	//4
	Sleep(50); Beep(880 / pt(7), 400);	//2
	Sleep(50); Beep(880 / pt(0), 400);  //6
	Sleep(50); Beep(880 / pt(0), 800);  //6-
}
void beep(float fre, float sec)
{
	Beep(fre, sec * 1000);
}